
/*
 * @author kanghua(kanghua151@msn.com) 
*/

#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <glib.h>
#include "hlfs.h"
#include "comm_define.h"
#include "misc.h"
#include "logger.h"

static int load_latest_inode(struct hlfs_ctrl *ctrl){
   int ret = 0;
   char *segfile_name = build_segfile_name(ctrl->last_segno);
   char *segfile_path = g_build_filename((char*)ctrl->storage_handler,segfile_name,NULL);
   int fd = open(segfile_path,O_RDONLY);
   if (fd<0){
       g_message("can not open file %s\n",segfile_path);
       ret = -1;
       goto out2;
    }
   uint64_t inode_pos = ctrl->last_offset - 
                        sizeof(struct inode_map_entry) -
                        sizeof(struct inode);
                                              
   g_message("inode pos  %llu\n",inode_pos);
   if(sizeof(struct inode) != 
            pread(fd,&ctrl->inode,
                 sizeof(struct inode),
                 inode_pos)){
       g_message("can not read inode from %s\n",segfile_path);
       ret = -1;
       goto out1;
    }
out1:
    close(fd);
out2:
    g_free(segfile_name);
    g_free(segfile_path);
    return ret;
}


/* flag ==0 readonly flag ==1 writeable */
int hlfs_open(struct hlfs_ctrl *ctrl , int flag){
    if(ctrl==NULL ||(flag !=0 && flag!=1)){
       g_message("error params :falg %d\n",flag);
       return -1;
    }
    int ret;
    g_message("inode no %llu , inode address %llu \n",ctrl->imap_entry.inode_no,ctrl->imap_entry.inode_addr);
    if(ctrl->imap_entry.inode_no == 0 && ctrl->imap_entry.inode_addr == 0){
       g_message("empty filesystem %s\n",ctrl->sb.fsname);
       if(flag == 0){
          g_message("must create it with writeable flag \n");
          return -1;
       }
       g_message("create new fs inode !\n");
       ctrl->inode.length = 0;
       ctrl->inode.mtime =  get_current_time();
       ctrl->inode.ctime =  get_current_time();
       ctrl->inode.atime =  get_current_time();
    }else{
       g_message("open exist fs %s\n",ctrl->sb.fsname);
       if(0!=load_latest_inode(ctrl)){
          g_message("fail to load inode !\n");
          return -1; 
       }
       g_message("inode 's length:%llu\n",ctrl->inode.length);
    }
    g_message("append log with only inode !\n");
    int size = append_inode(ctrl);
    if(size < 0){
       g_message("fail to append log with inode ! %d\n",size);
       return -1;
    }
    ctrl->last_offset+=size;
    return 0;
}
